﻿
Imports System.Text
Imports xmlctrl
Imports elpmis

Namespace lpmsservFunctions

    Friend Module xmlshare
        Friend Function matchcontrol(ByVal i As bare_variable) As Boolean
            Return Not i Is Nothing AndAlso i.variable().isType(typeDefination.var) AndAlso _
                   istype(Of xmlcontrol, Object)(i.value())
        End Function
    End Module

    'parameters, parent, the parent control need to add child into
    '            child, the child control need to add to parent
    'return, bool, whether the add is success or not
    Public Class xmladdchild
        Inherits internalFunction

        Public Class parameters
            Public Const parent As String = "parent"
            Public Const child As String = "child"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.parent, parameters.child)
        End Sub

        Public Sub New()
            MyBase.New("xml.addchild", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim parentv As bare_variable = Nothing
            Dim childv As bare_variable = Nothing
            parentv = ctx.findVariable(parameters.parent)
            childv = ctx.findVariable(parameters.child)
            If Not matchcontrol(parentv) OrElse Not matchcontrol(childv) Then
                raiseError("expect parameter " + parameters.parent + " and " + _
                           parameters.child + " are all xmlcontrols.", errorHandle.errorType.user)
                Return False
            Else
                Dim parent As xmlcontrol = Nothing
                Dim child As xmlcontrol = Nothing
                parent = convertor.cast(Of xmlcontrol)(parentv.value())
                child = convertor.cast(Of xmlcontrol)(childv.value())
                parent.addchild(child)
                output = New bare_variable(typeDefination.bool, True)
                Return True
            End If
        End Function
    End Class

    'parameters, tag, any, convert to string, the tag name of control need to be created
    'return, var, a pointer of xmlcontrol created
    Public Class xmlcreate
        Inherits internalFunction

        Public Class parameters
            Public Const tag As String = "tag"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.tag)
        End Sub

        Public Sub New()
            MyBase.New("xml.create", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim tag As bare_variable = Nothing
            tag = ctx.findVariable(parameters.tag)
            If tag Is Nothing Then
                raiseError("expect parameter " + parameters.tag, errorHandle.errorType.user)
                Return False
            Else
                output = New bare_variable(typeDefination.var, _
                                           httpServer2.currentContext().createControl(New xmlcontrol(tag:= _
                                                                                      Convert.ToString(tag.value()))))
                Return True
            End If
        End Function
    End Class

    'parameters, ctr, the control need to render, which should be created by xml.control.create
    'return, bool, whether render is success or not
    Public Class xmlrender
        Inherits internalFunction

        Public Class parameters
            Public Const ctr As String = "ctr"
            Public Const clear As String = "clear"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.ctr, parameters.clear)
        End Sub

        Public Sub New()
            MyBase.New("xml.render", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim ctrv As bare_variable = Nothing
            ctrv = ctx.findVariable(parameters.ctr)
            If Not matchcontrol(ctrv) Then
                raiseError("expect parameter " + parameters.ctr + " is a xmlcontrol.", errorHandle.errorType.user)
                Return False
            Else
                Dim ctr As xmlcontrol = Nothing
                ctr = convertor.cast(Of xmlcontrol)(ctrv.value())
                output = New bare_variable(typeDefination.bool, ctr.render())
                Dim clear As Boolean
                If Not ctx.findVariableBool(parameters.clear, clear) OrElse clear Then
                    ctr.clear()
                End If
                Return True
            End If
        End Function
    End Class

    'parameters, ctr, var, xmlcontrol, the control need to set attribute
    '            name, any, convert to string, the name of attribute
    '            value, any, convert to string, the value of attribute
    'return, bool, whether add attribute is success or not
    Public Class xmlattribute
        Inherits internalFunction

        Public Class parameters
            Public Const ctr As String = "ctr"
            Public Const name As String = "name"
            Public Const value As String = "value"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialMapping(m, parameters.ctr, parameters.name, parameters.value)
        End Sub

        Public Sub New()
            MyBase.New("xml.attribute", m)
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim ctrv As bare_variable = Nothing
            ctrv = ctx.findVariable(parameters.ctr)
            If Not matchcontrol(ctrv) Then
                raiseError("expect parameter " + parameters.ctr + " is a xmlcontrol.", errorHandle.errorType.user)
                Return False
            Else
                Dim name As bare_variable = Nothing
                Dim value As bare_variable = Nothing
                name = ctx.findVariable(parameters.name)
                value = ctx.findVariable(parameters.value)
                If name Is Nothing OrElse value Is Nothing Then
                    raiseError("expect parameter " + parameters.name + " or " + parameters.value, _
                               errorHandle.errorType.user)
                    Return False
                Else
                    Dim ctr As xmlcontrol = Nothing
                    ctr = convertor.cast(Of xmlcontrol)(ctrv.value())
                    ctr.attributes(Convert.ToString(name.value())) = Convert.ToString(value.value())
                    output = New bare_variable(typeDefination.bool, True)
                    Return True
                End If
            End If
        End Function
    End Class

    'parameters, ctr, var, xmlcontrol, the control need to set text
    '            text, any, convert to string, the text
    'return, bool, whether add text is success or not
    Public Class xmltext
        Inherits internalFunction

        Public Class parameters
            Public Const ctr As String = "ctr"
            Public Const text As String = "text"
        End Class

        Private Shared m As iParametersMapping = Nothing

        Shared Sub New()
            initialSerialMapping1(m, parameters.ctr, parameters.text)
        End Sub

        Public Sub New()
            MyBase.New("xml.text", m)
        End Sub

        Private Shared Function callback(ByVal name As String, ByVal var As String, ByRef obj As Object) As Boolean
            convertor.cast(Of StringBuilder)(obj).Append(var)
            Return True
        End Function

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            Dim ctr As xmlcontrol = Nothing
            If Not ctx.findVariable(parameters.ctr, ctr) Then
                raiseError("expect parameter " + parameters.ctr + " is a xmlcontrol.", errorHandle.errorType.user)
                Return False
            Else
                Dim sb As StringBuilder = Nothing
                sb = New StringBuilder()
                Dim rtn As Boolean
                If Not ctx.findVariables(AddressOf callback, string_finder(), parameters.text, obj:=sb) Then
                    'still check text, to match existing logic
                    Dim text As String = Nothing
                    If ctx.findVariableStr(parameters.text, text) Then
                        ctr.text = text
                        rtn = True
                    Else
                        rtn = False
                    End If
                Else
                    ctr.text = Convert.ToString(sb)
                    rtn = True
                End If
                free(sb)
                output = New bare_variable(typeDefination.bool, rtn)
                Return True
            End If
        End Function
    End Class

    'parameters, N/A
    'return, var, a pointer of a new xmltext, with no text encoding
    Public Class xmltextcreator
        Inherits internalFunction

        Public Class parameters
        End Class

        Public Sub New()
            MyBase.New("xml.xmltext.create")
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            output = New bare_variable(typeDefination.var, _
                                       currentContext().createControl(New xmlctrl.xmltext( _
                                                                      xmlcontrol.textEncodingEnum.none)))
            Return True
        End Function
    End Class

    'parameters, N/A
    'return, var, a pointer of a new container
    Public Class containercreator
        Inherits internalFunction

        Public Class parameters
        End Class

        Public Sub New()
            MyBase.New("xml.container.create")
        End Sub

        Protected Overrides Function invoke(ByVal ctx As context, ByRef output As bare_variable) As Boolean
            output = New bare_variable(typeDefination.var, _
                                       currentContext().createControl(New container()))
            Return True
        End Function
    End Class
End Namespace